// @ts-ignore
import * as  imageTools from 'image-tools';
import UPNG from "./UPNG.js";
/**
 * base64转文件
 * @param dataurl 
 * @param filename 
 */
function base64toFile(dataurl: any, filename = 'file'): File {
    let arr = dataurl.split(',');
    let mime = arr[0].match(/:(.*?);/)[1];
    let suffix = mime.split('/')[1];
    let bstr = atob(arr[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], `${filename}.${suffix}`, {
        type: mime,
    });
}
/**
 * @description 根据Blob 读取文件Buffer流
 * @param blob 
 * @returns 
 */
function readFile(blob: any) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsArrayBuffer(blob);
        reader.onload = function (event) {
            resolve(event);
        };
    });
}
/**
 * @description 获取图片的原始宽高尺寸
 * @param url 
 */
function getImageWidthHeight(url: string) {
    return new Promise(function (resolve, reject) {
        const image = new Image();
        image.onload = function () {
            resolve({ width: image.width, height: image.height });
        };
        image.onerror = function () {
            reject(new Error("load image error"));
        };
        image.src = url;
    });
}
/**
 * 获取解析图片数据
 * @param Files 
 * @returns 
 */
function getImgInfo(Files: FileList): Promise<any> {
    return new Promise((resolve, reject) => {
        if (!Files || Files.length === 0) reject('Files 不合法');
        for (let i = 0, l = Files.length; i < l; i++) {

            const file = Files[i];
            const { type } = file;
            const typeArr = type.split("/");
            if (typeArr[0] !== "image") return;
            let fileType = typeArr[1].toUpperCase();
            var reader = new FileReader();
            reader.onload = function (e: any) {
                const buffer = e.target.result;
                const imageType = getImageType_buffer(buffer);
                if (imageType) {
                    fileType = imageType;
                }
                const blob = new Blob([buffer]);
                fileOrBlobToDataURL(blob, function (dataUrl: string | null) {
                    if (dataUrl) {
                        const image = new Image();
                        image.onload = function () {
                            const width = image.width;
                            const height = image.height;
                            const imageData = getCanvasImgData(dataUrl, width, height);
                            if (imageData) {
                                const imgInfo = {
                                    name: file.name,
                                    fileType,
                                    size: file.size,
                                    width,
                                    height,
                                    imgUrl: dataUrl,
                                    imageData,
                                    blob,
                                };
                                resolve(imgInfo)
                            } else {
                                reject(null)
                            }
                        };
                        image.onerror = function () {
                            reject(null)
                        };
                        image.src = dataUrl;
                    } else {
                        reject(null)
                    }
                });
            };
            reader.readAsArrayBuffer(file);
        }
    })
}
/**
 * @description 获取图片二进制数据
 * @param imgUrl 
 * @param width 
 * @param height 
 * @returns 
 */
function getCanvasImgData(imgUrl: string, width: number = 0, height: number = 0) {
    if (imgUrl && width && height) {
        const img = new Image();
        img.src = imgUrl;
        const canvas = document.createElement("canvas") as HTMLCanvasElement;
        const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
        canvas.width = width;
        canvas.height = height;
        ctx.drawImage(img, 0, 0, width, height);
        const imageData = ctx.getImageData(0, 0, width, height) as ImageData;
        return imageData;
    }
    return null;
}
/**
 * @description File或Blob对象转DataURL
 * @param obj 
 */
function fileOrBlobToDataURL(obj: File | Blob, cb: (result: string | null) => void) {
    if (!obj) {
        cb(null);
        return;
    }
    const reader = new FileReader();
    reader.readAsDataURL(obj);
    reader.onload = function (e) {
        if (e.target) {
            cb(e.target.result as string);
        } else {
            cb(null);
        }
    };
}
/**
 * @description 根据图片文件流获取图片类型
 * @param buffer 
 */
function getImageType_buffer(buffer: ArrayBuffer) {
    let fileType = "";
    if (buffer) {
        const view = new DataView(buffer);
        const first4Byte = view.getUint32(0, false);
        const hexValue = Number(first4Byte).toString(16).toUpperCase();
        switch (hexValue) {
            case "FFD8FFDB":
                fileType = "JPG";
                break;
            case "FFD8FFE0":
            case "FFD8FFE1":
            case "FFD8FFE2":
            case "FFD8FFE3":
                fileType = "JPEG";
                break;
            case "89504E47":
                fileType = "PNG";
                break;
            case "47494638":
                fileType = "GIF";
                break;
            case "52494646":
                fileType = "WEBP";
                break;
            default:
                break;
        }
    }
    return fileType;
}
/**
 * 根据网络图片连接获取File文件格式
 * @param urls 
 * @returns 
 */
async function getFileByImageURL(urls: EmptyArrayType | string) {
    if (Array.isArray(urls)) {
        let downLoadTask = urls.map((url: string) => {
            return new Promise(async (resolve, reject) => {
                const response = await fetch(url);
                const data = await response.blob();
                resolve(await new File([data], getFileBaseByURL(url).name, { type: getFileTypeBySuffix(getFileBaseByURL(url).suffix) }))
            })
        })
        return Promise.all(downLoadTask)
    } else {
        const response = await fetch(urls);
        const data = await response.blob();
        return new File([data], getFileBaseByURL(urls).name, { type: getFileTypeBySuffix(getFileBaseByURL(urls).suffix) });
    }

}
/**
 * @description 根据路径获取文件的基本信息 名称以及后缀
 * @param url 
 * @returns 
 */
function getFileBaseByURL(url: string) {
    return { name: url.substr(url.lastIndexOf('/') + 1, url.lastIndexOf('.')), suffix: url.substr(url.lastIndexOf('.')) }
}
/**
 * @description 根据文件后缀获取文件类型 
 * @param suffix 
 */
function getFileTypeBySuffix(suffix: string): string {
    switch (suffix.toLowerCase().replace('.', '')) {
        case "jpg":
        case "jpeg":
        case "png":
        case "gif":
            return `image/${suffix.replace('.', '')}`;
        case "pdf":
            return "application/pdf";
        case "doc":
            return "application/msword";
        case "docx":
            return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        case "xls":
            return "application/vnd.ms-excel";
        case "xlsx":
            return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        case "ppt":
            return "application/vnd.ms-powerpoint";
        case "pptx":
            return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
        default:
            return "unknown";
    }
}
/**
 * @description Blob导出图片
 * @param blob 
 * @param imgName 
 * @returns 
 */
function exportToImage(blob: Blob, imgName: string) {
    if (!blob) return;
    var a = document.createElement("a");
    a.style.visibility = "hidden";
    document.body.appendChild(a);
    a.download = imgName;
    const objUrl = window.URL.createObjectURL(blob);
    a.href = objUrl;
    a.click();
    document.body.removeChild(a);
    window.URL.revokeObjectURL(objUrl);
}
/**
 * @description  上传完成图片压缩前事件
 * @param urls 图片压缩路径
 */
async function imageCompressionBefore(urls: string[]) {
    // let compressionTask = urls.map((url:string)=>{
    //     return new Promise((resolve,reject)=>{

    //     })
    // })
    let fileList = await getFileByImageURL(urls);
    console.log(fileList)
}
/**
 * @description 图片压缩
 * @param imageUrl 
 * @param width 
 * @param height 
 * @param imageType 
 * @param compressionDegree 
 * @param cb 
 */
function imageCompression(imageUrl: string | ImageData, width: number, height: number, imageType: string, compressionDegree: number, cb: (blob: Blob | null) => void) {
    if (imageUrl && imageType) {
        const degree = compressionDegree / 100;
        if (["JPG", "JPEG"].includes(imageType.toUpperCase())) {
            const img = new Image();
            img.src = imageUrl as string;
            const canvas = document.createElement("canvas") as HTMLCanvasElement;
            const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
            canvas.width = width;
            canvas.height = height;
            ctx.drawImage(img, 0, 0, width, height);
            canvas.toBlob(
                (blob: Blob | null) => {
                    cb && cb(blob);
                },
                `image/${imageType.toLowerCase()}`,
                degree
            );
        } else {
            const bit = Math.floor(degree * 256);
            const png = UPNG.encode(
                [(imageUrl as ImageData).data.buffer],
                width,
                height,
                bit
            );
            const blob = new Blob([png]);
            cb && cb(blob);
        }
    } else {
        cb && cb(null);
    }
}

export default {
    ...imageTools,
    base64toFile,
    readFile,
    getImageWidthHeight,
    getImgInfo,
    getFileByImageURL,
    getFileBaseByURL,
    getFileTypeBySuffix,
    exportToImage,
    imageCompressionBefore,
    imageCompression,
}